Option Explicit

'################################################################
' Discriptor
' DFFilter 条件定义接口实现
' 单列的 [between] 比较
'################################################################

Implements IDFFilterColCondition

'################################################################
' Field
'################################################################
' 原始列，可以是真实列 DFFilterSingleCol 或者其他包装类型
Private originCol As IDFFilterCol

' 比较参数数组
Private fieldCompareVal() As Variant

'################################################################
' Constructor
'################################################################
Private Sub Class_Initialize()
End Sub

Private Sub Class_Terminate()
End Sub

'################################################################
' Init
'################################################################
' @param col 计算列
' @param vs 比较数据数组
'                   每个数组元素的类型应该和 col 相容
'                   INT, DECIMAL 可以相容
'                   DF_DATE, DF_TIME, DF_TIMESTAMP 可以相容
Public Sub Init(ByRef col As IDFFilterCol, ByRef vs As Variant)
    ' 1. 检查参数
    ' 1.1 列不能为空
    If col Is Nothing Then
        Err.Raise 10001, Description:="parameter col must be not nothing"
        Exit Sub
    End If

    ' 1.2 列的类型不能是聚合列或组合式聚合列
    If col.isAggregateCol Then
        Err.Raise 10311, Description:="Aggregate Column Parameter [col] can not use in condition"
        Exit Sub
    End If

    ' 2. 检查比较数组参数
    ' 2.1 vs 必须是数组
    If IsArray(vs) = False Then
        Err.Raise 10005, Description:="parameter vs must be Array"
        Exit Sub
    End If

    ' 2.2 检查 vs 的数量
    Dim vsIdxMin As Integer
    Dim vsIdxMax As Integer
    Dim vsSize As Integer
    vsIdxMin = LBound(vs)
    vsIdxMax = UBound(vs)
    vsSize = vsIdxMax - vsIdxMin + 1
    If vsSize = 0 Then
        Err.Raise 10006, Description:="Array parameter vs's size must not be 0"
        Exit Sub
    End If

    ' 2.3 检查 col + vs 的类型
    ' 2.3.1 如果 vs(i) 是 Empty，则不需要比较
    ' 2.3.2 如果 vs(i) 不是 Empty，则需要比较两者的类型是否相容
    ReDim fieldCompareVal(0 To (vsSize - 1)) As Variant

    Dim i As Integer
    Dim v As Variant
    Dim valType As DF_DataType
    Dim colType As DF_DataType
    colType = col.ColType

    For i = 0 To (vsSize - 1)
        v = vs(vsIdxMin + i)

        ' 检查类型是否相容
        If Not IsEmpty(v) Then
            valType = DFHelper.getDataTypeForPrimitiveData(v)

            If colType <> valType Then
                If (colType = DF_DataType.DF_INT Or colType = DF_DataType.DF_DECIMAL) And _
                (valType = DF_DataType.DF_INT Or valType = DF_DataType.DF_DECIMAL) Then
                    ' 如果两者的类型是 INT 或 DECIMAL 则类型相容
                    ' noop
                ElseIf (colType = DF_DataType.DF_DATE Or colType = DF_DataType.DF_TIME Or colType = DF_DataType.DF_TIMESTAMP) And _
                    (valType = DF_DataType.DF_DATE Or valType = DF_DataType.DF_TIME Or valType = DF_DataType.DF_TIMESTAMP) Then
                    ' noop
                        ' 如果两者的类型是 DF_DATE, DF_TIME, DF_TIMESTAMP 可以相容
                Else
                    Err.Raise 10302, Description:="parameter type of col and vs(" & i & ") is not same: col Type=" & _
                                    DFHelper.getDataTypeName(colType) & _
                                    ", vs(" & i & ") Type=" & DFHelper.getDataTypeName(valType)
                    Exit Sub
                End If
            End If
        End If

        ' 保存符合规则的比较数据
        fieldCompareVal(i) = v
    Next

    ' 3. 保存基本参数
    Set originCol = col
End Sub

'################################################################
' Function
'################################################################
' 检查 DFFilter 的活动行的数据是否符合规则
' 外部不应该主动调用
Public Function IDFFilterColCondition_unsafeCheckActiveRowVal() As Boolean
    ' 计算当前列的结果
    Dim curComputedVal As Variant
    curComputedVal = originCol.unsafeGetActiveRowVal()

    ' 和所有的比较数据进行比较，只要有一个符合规则，就停止并返回 True
    Dim v As Variant
    For Each v In fieldCompareVal
        If curComputedVal = v Then
            IDFFilterColCondition_unsafeCheckActiveRowVal = True
            Exit Function
        End If
    Next

    IDFFilterColCondition_unsafeCheckActiveRowVal = False
End Function

' 返回当前条件是不是只使用了一个 Filter
Public Function IDFFilterColCondition_isUseSingleFilter() As Boolean
    IDFFilterColCondition_isUseSingleFilter = originCol.isUseSingleFilter
End Function

' 返回当前条件中是否使用了 Filter
' 因为存在如: And 1=1 这样的全字面量条件
Public Function IDFFilterColCondition_isUseFilter() As Boolean
    ' 如果 originCol 是字面量列，则当前条件是全字面量条件, 返回 False
    IDFFilterColCondition_isUseFilter = (Not originCol.isLiteralCol)
End Function

' 获取当前条件中使用的所有 Filter
' @return HashSet<DFFilter>
Public Function IDFFilterColCondition_getAllFilters() As ISet
    Set IDFFilterColCondition_getAllFilters = originCol.getAllFilters
End Function

' 检查当前条件使用的 DFFilter 是否和指定的 DFFilter 相同
' 如果条件中使用了多个 Filter，则返回 False
' 如果是全字面量列，则返回 False
Public Function IDFFilterColCondition_isSameFilter(ByRef filter As DFFilter) As Boolean
    IDFFilterColCondition_isSameFilter = originCol.isSameFilter(filter)
End Function